package net.lzzy.practices.wed.course;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import net.lzzy.practices.constants.ApiConstants;
import net.lzzy.practices.constants.Messages;
import net.lzzy.practices.entities.Applicant;
import net.lzzy.practices.entities.Course;
import net.lzzy.practices.services.ApplicantService;
import net.lzzy.practices.utils.StringUtils;
import net.lzzy.practices.wed.models.ApiResult;
import net.lzzy.practices.wed.models.ApplicantInfo;
import net.lzzy.practices.wed.models.VmApplicant;
import net.lzzy.practices.wed.models.VmCourse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Api(tags = "注册相关业务")
@CrossOrigin
@RestController
@RequestMapping(ApiConstants.ROUTE_APPLICANT_ROOT)
public class ApplicantApiController {
    private final ApplicantService service;

    @Autowired
    public ApplicantApiController(ApplicantService service){
        this.service = service;
    }

    @ApiOperation(value = "学生申请注册课程", notes = "<b>参数包括：</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>1.token(String)<br/>" +
            "2.studentId(String)<br/>3.courseId(String)<br/>")
    @ApiImplicitParam(name = "json", value = "注册课程信息", dataType = "ApplicantInfo", dataTypeClass = ApplicantInfo.class, paramType = "body")
    @PostMapping(ApiConstants.ROUTE_APPLICANT_APPLY)
    public ApiResult apply(@RequestBody ApplicantInfo info){
        String token = info.getToken();
        String strCourseId = info.getCourseId();
        String strStudentId = info.getStudentId();
        if (StringUtils.isEmpty(token) ||
                StringUtils.isEmpty(strCourseId) ||
                StringUtils.isEmpty(strStudentId)){
            return new ApiResult(false, Messages.INCOMPLETE_INFO.toString(), null);
        }
        UUID studentId = UUID.fromString(strStudentId);
        UUID courseId = UUID.fromString(strCourseId);
        Applicant applicant = service.apply(studentId, courseId,token);
        if (applicant == null){
            String msg = Messages.NO_PERMISSION + "或" + Messages.WRONG_ID;
            return new ApiResult(false, msg, null);
        }
        return  new ApiResult( true,Messages.SUCCESS.toString(),new VmApplicant(applicant));
    }

    @ApiOperation(value = "获取某一学生已获审批的申请", notes = "<b>参数列表：</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.token(String)<br/>&nbsp;&nbsp;&nbsp;&nbsp;2.studentId(UUID)<br/>")
    @GetMapping(ApiConstants.ROUTE_APPLICANT_ENROLLED)
    public ApiResult getEnrolledCourses(@RequestParam String token,@RequestParam(name = "id") UUID studentId){
        List<Applicant> applicants = service.getEnrolledApplicants(studentId);
        return transform(applicants);
    }

    @GetMapping(ApiConstants.ROUTE_APPLICANT_APPLYING)
    public ApiResult getApplyingCourses(@RequestParam String token,@RequestParam(name = "id") UUID studentId){
        List<Applicant> applicants = service.getApplyingApplicants(studentId);
        return transform(applicants);
    }

    @ApiOperation(value = "获取某一学生正在等待审批的申请", notes = "<b>参数列表：</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.token(String)<br/>&nbsp;&nbsp;&nbsp;&nbsp;2.studentId(UUID)<br/>")
    private ApiResult transfrom(List<Applicant> applicants){
        if (applicants == null){
            return new ApiResult(false, Messages.WRONG_ID.toString(),null);
        }
        List<Applicant> vmApplicants = new ArrayList<>();
        applicants.forEach(applicant -> vmApplicants.add(new VmApplicant(applicant)));
        return new ApiResult(true, applicants.size() + "",vmApplicants);
    }

    @ApiOperation(value = "教师审批学生申请", notes = "<b>参数列表：</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.token(String)<br/>&nbsp;&nbsp;&nbsp;&nbsp;2.applicantId(UUID)<br/>")
    @PostMapping(ApiConstants.ROUTE_APPLICANT_APPROVE)
    public ApiResult approve(@RequestParam String token,@RequestParam(name = "id") UUID applicantId){
        Applicant applicant = service.approve(applicantId,token);
        if (applicant == null){
            String msg = Messages.NO_PERMISSION + "或" + Messages.WRONG_ID;
            return new ApiResult(false, msg,null);
        }
        return new ApiResult(true, Messages.SUCCESS.toString(),new VmApplicant(applicant));
    }

    @ApiOperation(value = "教师驳回学生申请", notes = "<b>参数列表：</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.token(String)<br/>&nbsp;&nbsp;&nbsp;&nbsp;2.applicantId(UUID)<br/>")
    @PostMapping(ApiConstants.ROUTE_APPLICANT_DECLINE)
    public ApiResult decline(@RequestParam String token,@RequestParam(name = "id") UUID applicantId){
        Applicant applicant = service.approve(applicantId,token);
        if (applicant == null){
            String msg = Messages.NO_PERMISSION + "或" + Messages.WRONG_ID;
            return new ApiResult(false, msg,null);
        }
        return new ApiResult(true, Messages.SUCCESS.toString(),new VmApplicant(applicant));
    }

    @ApiOperation(value = "获取正在申请某课程的所有申请", notes = "<b>参数列表：</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.token(String)<br/>&nbsp;&nbsp;&nbsp;&nbsp;2.courseId(UUID)<br/>")
    @GetMapping(ApiConstants.ROUTE_APPLICANT_TEACHER_APPLYING)
    public ApiResult getApplyingStudents(@RequestParam String token,@RequestParam(name = "id") UUID consentId){
        List<Applicant> applicants = service.getApplyingStudents(consentId);
        return transform(applicants);
    }

    @ApiOperation(value = "获取某课程已审批的所有申请", notes = "<b>参数列表：</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.token(String)<br/>&nbsp;&nbsp;&nbsp;&nbsp;2.courseId(UUID)<br/>")
    @GetMapping(ApiConstants.ROUTE_APPLICANT_TEACHER_ENROLLED)
    public ApiResult getEnrolledStudents(@RequestParam String token,@RequestParam(name = "id") UUID consentId){
        List<Applicant> applicants = service.getEnrolledStudents(consentId);
        return transform(applicants);
    }

    @ApiOperation(value = "获取已驳回的某课程的申请", notes = "<b>参数列表：</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.token(String)<br/>&nbsp;&nbsp;&nbsp;&nbsp;2.courseId(UUID)<br/>")
    @GetMapping(ApiConstants.ROUTE_APPLICANT_TEACHER_DELINED)
    public ApiResult getDesclingStudents(@RequestParam String token,@RequestParam(name = "id") UUID consentId){
        List<Applicant> applicants = service.getDesclingStudents(consentId);
        return transform(applicants);
    }

    private ApiResult transform(List<Applicant> applicants) {
        if(applicants == null){
            return new ApiResult(false, Messages.WRONG_ID.toString(), null);
        }
        List<VmApplicant> vmApplicants = new ArrayList<>();
        applicants.forEach(applicant -> vmApplicants.add(new VmApplicant(applicant)));
        return new ApiResult(true, applicants.size() + "", vmApplicants);
    }

    @ApiOperation(value = "移除已正式注册了某课程的学生", notes = "<b>参数包括：</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>1.token(String)<br/>" +
            "&nbsp;&nbsp;&nbsp;&nbsp;2.studentId(String)<br/>&nbsp;&nbsp;&nbsp;&nbsp;3.courseId(String)<br/>")
    @PostMapping(ApiConstants.ROUTE_APPLICANT_REMOVE)
    public ApiResult remove(@RequestBody ApplicantInfo info){
        String token = info.getToken();
        String strCourseId = info.getCourseId();
        String strStudentId = info.getStudentId();
        if (StringUtils.isEmpty(token) ||
                StringUtils.isEmpty(strCourseId) ||
                StringUtils.isEmpty(strStudentId)){
            return new ApiResult(false, Messages.INCOMPLETE_INFO.toString(), null);
        }
        UUID studentId = UUID.fromString(strStudentId);
        UUID courseId = UUID.fromString(strCourseId);
        Course course = service.removeStudent(courseId,studentId,token);
        if (course == null){
            String msg = Messages.NO_PERMISSION + "或" + Messages.WRONG_ID;
            return new ApiResult(false, msg, null);
        }
        return new ApiResult(true,Messages.SUCCESS.toString(), VmCourse.create(course,true));
    }

    @GetMapping(ApiConstants.ROUTE_APPLICANT_DECLINED)
    public ApiResult getDeclinedCourses(@RequestParam String token, @RequestParam(name = "id") UUID studentId) {
        List<Applicant> applicants = service.getDeclinedApplicants(studentId);
        return transform(applicants);
    }
}
